import json
import os
import subprocess
import sys
from datetime import datetime

from PySide6.QtCore import QTimer, Qt, QThread, Signal
from PySide6.QtGui import QFont
from PySide6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
                               QWidget, QLabel, QTextEdit, QPushButton, QFrame,
                               QProgressBar)


class CommandWorker(QThread):
    """工作线程，用于执行系统命令避免界面冻结"""
    command_output = Signal(str)
    command_error = Signal(str)

    def __init__(self, command):
        super().__init__()
        self.command = command

    def run(self):
        try:
            # 执行系统命令
            result = subprocess.run(
                self.command,
                shell=True,
                capture_output=True,
                text=True,
                timeout=10
            )

            if result.returncode == 0:
                self.command_output.emit(result.stdout)
            else:
                self.command_error.emit(f"命令执行失败 (返回码: {result.returncode}):\n{result.stderr}")

        except subprocess.TimeoutExpired:
            self.command_error.emit("命令执行超时")
        except Exception as e:
            self.command_error.emit(f"执行命令时发生错误: {str(e)}")

class HAStatusMonitor(QMainWindow):
    def __init__(self):
        super().__init__()
        self.json_file_path = "/etc/keepalived/state"  # JSON状态文件路径
        self.init_ui()
        self.setup_timer()

    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle("双机热备份状态监控")
        self.setGeometry(100, 100, 900, 700)

        # 设置主窗口部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # 创建主布局
        main_layout = QVBoxLayout(central_widget)
        main_layout.setSpacing(10)
        main_layout.setContentsMargins(15, 15, 15, 15)

        # 状态指示器
        self.status_indicator = QLabel("系统就绪")
        self.status_indicator.setAlignment(Qt.AlignCenter)
        self.status_indicator.setStyleSheet("background-color: #ecf0f1; padding: 5px; border-radius: 3px;")
        main_layout.addWidget(self.status_indicator)

        # 进度条（用于命令执行时显示）
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        main_layout.addWidget(self.progress_bar)

        # 双机热备份状态区域
        ha_status_frame = self.create_ha_status_frame()
        main_layout.addWidget(ha_status_frame)

        # Keepalived状态区域
        keepalived_frame = self.create_keepalived_frame()
        main_layout.addWidget(keepalived_frame)

        # 控制按钮
        button_layout = self.create_control_buttons()
        main_layout.addLayout(button_layout)

    def create_ha_status_frame(self):
        """创建双机热备份状态显示区域"""
        frame = QFrame()
        frame.setFrameStyle(QFrame.Box)
        frame.setLineWidth(1)
        frame.setStyleSheet("QFrame { border: 1px solid #bdc3c7; border-radius: 5px; }")

        layout = QVBoxLayout(frame)

        # 标题栏
        title_layout = QHBoxLayout()

        status_title = QLabel("双机热备份状态")
        status_font = QFont()
        status_font.setPointSize(12)
        status_font.setBold(True)
        status_title.setFont(status_font)
        title_layout.addWidget(status_title)

        title_layout.addStretch()
        layout.addLayout(title_layout)

        # 状态显示区域 - 使用QLabel而不是QTextEdit
        self.ha_status_label = QLabel("当前状态：无")
        self.ha_status_label.setAlignment(Qt.AlignCenter)
        self.ha_status_label.setStyleSheet("""
            QLabel {
                background-color: #f8f9fa;
                border: 1px solid #dee2e6;
                border-radius: 3px;
                padding: 15px;
                font-size: 16px;
                font-weight: bold;
            }
        """)
        layout.addWidget(self.ha_status_label)

        return frame

    def create_keepalived_frame(self):
        """创建Keepalived状态显示区域"""
        frame = QFrame()
        frame.setFrameStyle(QFrame.Box)
        frame.setLineWidth(1)
        frame.setStyleSheet("QFrame { border: 1px solid #bdc3c7; border-radius: 5px; }")

        layout = QVBoxLayout(frame)

        # 标题栏
        title_layout = QHBoxLayout()

        log_title = QLabel("Keepalived服务状态")
        log_font = QFont()
        log_font.setPointSize(12)
        log_font.setBold(True)
        log_title.setFont(log_font)
        title_layout.addWidget(log_title)

        title_layout.addStretch()
        layout.addLayout(title_layout)

        # 状态显示区域
        self.keepalived_text = QTextEdit()
        self.keepalived_text.setReadOnly(True)
        self.keepalived_text.setStyleSheet("""
            QTextEdit {
                background-color: #f8f9fa;
                border: 1px solid #dee2e6;
                border-radius: 3px;
                padding: 8px;
                font-family: 'Courier New', monospace;
            }
        """)
        self.keepalived_text.setPlaceholderText("等待获取Keepalived服务状态...")
        layout.addWidget(self.keepalived_text)

        return frame

    def create_control_buttons(self):
        """创建控制按钮"""
        button_layout = QHBoxLayout()

        # 刷新按钮
        self.refresh_btn = QPushButton("🔄 刷新状态")
        self.refresh_btn.clicked.connect(self.refresh_all_status)
        self.refresh_btn.setStyleSheet("""
            QPushButton {
                background-color: #3498db;
                color: white;
                border: none;
                padding: 8px 15px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #2980b9;
            }
        """)
        button_layout.addWidget(self.refresh_btn)

        button_layout.addStretch()

        # 退出按钮
        self.exit_btn = QPushButton("🚪 退出")
        self.exit_btn.clicked.connect(self.close)
        self.exit_btn.setStyleSheet("""
            QPushButton {
                background-color: #95a5a6;
                color: white;
                border: none;
                padding: 8px 15px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #7f8c8d;
            }
        """)
        button_layout.addWidget(self.exit_btn)

        return button_layout

    def setup_timer(self):
        """设置定时器，自动刷新状态"""
        self.timer = QTimer()
        self.timer.timeout.connect(self.refresh_all_status)
        self.timer.start(5000)  # 每10秒刷新一次

        # 立即执行一次刷新
        self.refresh_all_status()

    def read_ha_status(self):
        """读取双机热备份状态JSON文件，返回简化的状态信息"""
        try:
            if not os.path.exists(self.json_file_path):
                return "当前状态：无"

            with open(self.json_file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)

            # 根据current_host字段确定状态
            standbyStatus = data.get('standbyStatus', 0)
            if standbyStatus == 0:
                return "当前状态：主机"
            elif standbyStatus == 1:
                return "当前状态：备机"
            else:
                return "当前状态：未知"

        except Exception as e:
            return "当前状态：数据错误"

    def get_keepalived_status(self):
        """获取Keepalived服务状态"""
        self.progress_bar.setVisible(True)
        self.progress_bar.setRange(0, 0)  # 无限进度条

        # 在工作线程中执行命令
        self.command_worker = CommandWorker("systemctl status keepalived")
        self.command_worker.command_output.connect(self.on_keepalived_output)
        self.command_worker.command_error.connect(self.on_keepalived_error)
        self.command_worker.start()

    def on_keepalived_output(self, output):
        """处理Keepalived状态命令输出"""
        self.progress_bar.setVisible(False)

        status_text = f"🖥️ Keepalived服务状态 (更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')})\n\n"
        status_text += output
        self.keepalived_text.setPlainText(status_text)

        # 滚动到底部
        self.keepalived_text.verticalScrollBar().setValue(
            self.keepalived_text.verticalScrollBar().maximum()
        )

    def on_keepalived_error(self, error_message):
        """处理Keepalived状态命令错误"""
        self.progress_bar.setVisible(False)

        error_text = f"❌ 获取Keepalived状态失败 (更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')})\n\n"
        error_text += f"错误信息: {error_message}"

        self.keepalived_text.setPlainText(error_text)

    def refresh_all_status(self):
        """刷新所有状态显示"""
        self.status_indicator.setText(f"最后更新: {datetime.now().strftime('%H:%M:%S')}")

        # 更新双机热备份状态
        ha_status = self.read_ha_status()
        self.ha_status_label.setText(ha_status)

        # 更新Keepalived服务状态
        self.get_keepalived_status()

    def clear_display(self):
        """清空显示内容"""
        self.ha_status_label.setText("当前状态：无")
        self.keepalived_text.clear()

def main():
    app = QApplication(sys.argv)

    # 设置应用样式
    app.setStyle('Fusion')

    window = HAStatusMonitor()
    window.show()

    sys.exit(app.exec())

if __name__ == '__main__':
    main()